#!/usr/bin/env python

# This file is part of the Buildext project
# Copyright (C) 2010-2011 Raymond Bosman <rbosman@gmail.com>
# Copyright (C) 2010-2011 Rene Molenaar <megamillerzoid@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.


__author__  = ["Raymond Bosman", "Rene Molenaar"]
__version__ = "0.4.0"
__doc__     = """
%prog <target> [target2] [...] 

For example: '%prog boost'
Builds boost for the current host machine.

To see available targets, run: %prog --targets
"""

import sys
import glob
import types

if sys.hexversion < 0x2050000:
  sys.exit( "Error: Python 2.5.0 or higher is needed" )

import platform
import os
import os.path
from optparse import OptionParser
from source.machine import *
from source.build import *
import shutil

# Set up the command line.
parser = OptionParser(usage= __doc__)

# Build Directories
parser.add_option( "-t", "--temp-dir",        dest="tempdir", default="tmp", help="Temporary directory" )
parser.add_option( "-d", "--download-dir",    dest="downloaddir", default="downloads", help="Download directory (using '"+os.path.abspath("downloads")+"')" )
parser.add_option( "-e", "--enviro-dir",      dest="envirodir", default="enviro", help="Enviro (install) directory (using '"+os.path.abspath("enviro")+"')" )
parser.add_option( "-a", "--add-library",     dest="libraries",  help="Search an additional directory for build targets" )

# Target information
parser.add_option( "", "--targets",           dest="show_targets", default=False, action="store_true", help="print available groups and targets" )
parser.add_option( "-i", "--info",            dest="info", default=False, action="store_true", help="Show the information of the given target(s)" )
parser.add_option( "-l", "--list-dependencies",  dest="show_dependencies", default=False, action="store_true", help="List all dependencies for the given target(s)" )
parser.add_option( "", "--revdeps",  dest="show_reverse_dependencies", default=False, action="store_true", help="List all reverse dependencies for the given target" )
parser.add_option( "-s", "--showenv",     dest="generate_environment", default=False, action="store_true", help="print set or export variables" )

# Configuration
parser.add_option( "",   "--clear-builddir",  dest="clear_builddir", default=False, action="store_true", help="clear build directory" )
parser.add_option( "", "--bits",              dest="bits",  type="int", default=None, help="Build for 32 or 64 bits" )
parser.add_option( "", "--skip-dependencies", dest="builddependencies", default=True, action="store_false", help="Skip building dependencies" )
parser.add_option( "-n", "--no-rebuilds",     dest="rebuilds", default=True, action="store_false", help="indicate that buildext should not rebuild already build package(s)" )
parser.add_option( "-j", "--jobs",            dest="jobs", type="int", default=None, help="Specifies the number of jobs (commands) to run simultaneously for supporting builders " )
parser.add_option( "", "--continue",          dest="continueonerrors", default=False, action="store_true", help="Continue on errors" )

# Other
parser.add_option( "", "--version",           dest="version", default=False, action="store_true", help="Show the version of buildext" )
parser.add_option( "", "--machine-info",    dest="machine_info", default=False, action="store_true", help="Show the machine information" )
parser.add_option( "", "--dir-info",    dest="dir_info", default=False, action="store_true", help="Show the directories information" )
parser.add_option( "", "--summary",    dest="showsummary", default=False, action="store_true", help="Show build summary after build completion" )

parser.add_option( "-v", "--verbose",  dest="verbose", default=False, action="store_true", help="Show verbose information. Parameter can be combined with -i' and '--targets'" )
parser.add_option( "", "--self-test",  dest="selftest", default=False, action="store_true", help="Test all targets" )
parser.add_option( "", "--url-test",  dest="urltest", default=False, action="store_true", help="Check if url exists for all targets" )



if __name__ == '__main__' :
  (options, target) = parser.parse_args()

  if options.version:
    print "Buildext %s" % __version__
    exit(0)

  #TODO Set default values from machine. (eg bits, tempdir, platform, etc)
  machine = Machine(bits = options.bits,  cores = options.jobs)
  directories = Directories( machine, tempdir=options.tempdir, downloaddir=options.downloaddir, envirodir=options.envirodir)
  configuration = Configuration(machine, directories, options.verbose, options.rebuilds, options.builddependencies, options.continueonerrors, options.showsummary)
  build = Build(configuration, os.path.abspath( sys.path[0] + os.sep + "library" ) )

  if options.tempdir == options.envirodir:
    print "Error: Temp directory and Target Environment directory cannot be the same directory."
    exit(0)

  if options.machine_info:
    machine.print_info()
    exit(0)

  if options.dir_info:
    directories.print_info()
    exit(0)

  if options.libraries:
    l = options.libraries.split(os.path.pathsep) 
    build.addlibraries(l)

  if options.show_reverse_dependencies:
    mytarget = target[0]
    result = []
    for mytarget in target:
      for systargets in build.targets()[1:]:
       if mytarget in [deps.target.name for deps in build.dependencies([systargets.name]) ]:
         if systargets.name not in result:
           result.append(systargets.name)

    for r in result:
      print r
    exit(0)

  if options.show_targets:
    for t in build.targets():
      t.print_info(options.verbose)
    exit(0)

  if options.info:
    for t in target:
      build.runtimetarget(t).print_info(True)
    exit(0)

  if options.show_dependencies:
    for t in build.dependencies(target):
      t.print_info(options.verbose)
    exit(0)

  if options.generate_environment:
    build.generate_environment( target )
    exit(0)

  # Clear directories
  if options.clear_builddir:
    print "Clearing builddir"
    shutil.rmtree( directories.build )
    os.makedirs( directories.build )

  if options.selftest:
    build.build_all()

  if options.urltest:
    build.checkurl_all()

  if not build.build_targets( target ):
    exit(1)

